package sf.querydsl.dao;

import com.querydsl.core.types.Predicate;
import com.querydsl.sql.AbstractSQLQuery;
import com.querydsl.sql.Configuration;
import com.querydsl.sql.SQLTemplates;
import com.querydsl.sql.dml.SQLDeleteClause;
import com.querydsl.sql.dml.SQLInsertClause;
import com.querydsl.sql.dml.SQLMergeClause;
import com.querydsl.sql.dml.SQLUpdateClause;
import sf.common.wrapper.Page;
import sf.core.DBObject;

import javax.inject.Provider;
import java.sql.Connection;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Stream;

public interface DBQueryDSL {

    /**
     * @param readonly
     * @return
     */
    SQLTemplates queryDSLSQLTemplates(boolean readonly);

    /**
     * QueryDSL支持，返回一个QueryDSL的查询对象，可以使用QueryDSL进行数据库操作(存在连接泄漏风险)
     * @param tableClass 注册自定义类型,主要是对Map映射为json的支持.
     * @return SQLQuery
     * @see com.querydsl.sql.SQLQuery
     */
    Configuration queryDSLConfiguration(Class<? extends DBObject>... tableClass);

    /**
     * @param readonly
     * @return
     */
    Provider<Connection> queryDSLProvider(boolean readonly);

    /**
     * 是否存在
     * @param predicates
     * @param clz
     * @param <T>
     * @return
     */
    <T extends DBObject> boolean queryDSLExists(List<Predicate> predicates, Class<T> clz);

    /**
     * @param query
     * @param returnClass
     * @param <T>
     * @return map或单一类型, 或bean实体类
     */
    <T> List<T> queryDSLSelectList(AbstractSQLQuery<?, ?> query, Class<T> returnClass);

    /**
     * sqlserver2000分页有bug
     * @param query
     * @param start 必须为数字(<0,将忽略该参数)
     * @param limit 必须为>=0的数字
     * @param <T>
     * @return map或单一类型, 或bean实体类
     */
    <T> Page<T> queryDSLSelectPage(AbstractSQLQuery<?, ?> query, Class<T> returnClass, long start, int limit);

    /**
     * @param query
     * @param <T>
     * @return map或单一类型, 或bean实体类
     */
    <T> T queryDSLSelectOne(AbstractSQLQuery<?, ?> query, Class<T> returnClass);

    /**
     * @param ormIt
     * @param beanClass
     * @param query
     * @param <T>
     */
    <T> void queryDSLSelectIterator(Consumer<Iterable<T>> ormIt, Class<T> beanClass, AbstractSQLQuery<?, ?> query);

    /**
     * @param ormStream
     * @param beanClass
     * @param query
     * @param <T>
     */
    <T> void queryDSLSelectStream(Consumer<Stream<T>> ormStream, Class<T> beanClass, AbstractSQLQuery<?, ?> query);

    /**
     * @param insert
     * @return
     */
    int queryDSLInsert(SQLInsertClause insert);

    /**
     * @param insert
     * @param keyValues
     * @return
     */
    int queryDSLInsert(SQLInsertClause insert, List<Map<String, Object>> keyValues);

    /**
     * @param update
     * @return
     */
    int queryDSLUpdate(SQLUpdateClause update);

    /**
     * @param delete
     * @return
     */
    int queryDSLDelete(SQLDeleteClause delete);

    /**
     * merge into 只有oracle支持
     * @param merge
     * @return
     */
    int queryDSLMerge(SQLMergeClause merge);

    /**
     * merge into 只有oracle支持
     * @param merge
     * @param keyValues
     * @return
     */
    int queryDSLMerge(SQLMergeClause merge, List<Map<String, Object>> keyValues);
}
